#pragma once

#include <MyFC/Widget.h>
#include <MyFC/Container.h>
#include <list>
#include "Types.h"
#include "DLL.h"

namespace My {

class Panel;
class PanelBar;
class Frame;

typedef std::list<Panel *>	PanelList;
typedef PanelList::iterator	PanelIndex;

/**
 * Base class for embedded panels
 */
class DLL_API Panel : public My::Container, public My::Widget 
{
public:
	enum { 
		ALIGN_CLIENT,
		ALIGN_LEFT,	
		ALIGN_RIGHT,
		ALIGN_TOP,
		ALIGN_BOTTOM
	};
	friend class PanelBar;
protected:
	Frame &		m_Frame;
	PanelBar *	m_pOwner;
	PanelIndex	m_Index;
	String		m_Caption;
	int			m_Alignment;
protected:
	virtual CSize GetMinClientSize() const = 0;
public:
	Panel(Frame &);
public:
	const String & GetCaption() const
		{ return m_Caption; }
	int GetAlignment() const
		{ return m_Alignment; }
	CSize GetMinWindowSize() const;
public:
	int GetHeaderHeight() const;
public:
	void SetCaption(const String & s);
	void SetAlignment(int a);
public:
	virtual void HandlePaint(CDC * pDC, const CRect & r);
};

/**
 * Panel containing a single widget
 */
class DLL_API WidgetPanel : public Panel {
private:
	Widget &	m_Widget;
	int			m_Border;
public:
	WidgetPanel(Frame & f, Widget & w, int b = 0) 
		: Panel(f), m_Widget(w), m_Border(b)
	{
		Add(&m_Widget);
	}
protected:
	virtual CSize GetMinClientSize() const;
	virtual void LayoutControls();
};

/**
 * PanelBar is a group of panels layed out along
 * a single frame side
 */
class DLL_API PanelBar : public My::Container {  
protected:
	Frame &		m_Frame;
	PanelList	m_Panels;
public:
	PanelBar(Frame &);
	~PanelBar();
public:
	CSize GetMinWindowSize() const;
public:
	void AddPanel(Panel * pPanel);
	void RemovePanel(Panel * pPanel);
	WidgetPanel * AddWidget(Widget &, const String & caption, int alignment = Panel::ALIGN_CLIENT, int border = 0);
	virtual void LayoutControls();
public:
	virtual void HandleVisible(bool on);
	virtual void HandlePaint(CDC * pDC, const CRect & r);
private:
	std::list<WidgetPanel *>	m_AutoPanels;
};

/**
 * Sample panel for testing purposes
 */
class DLL_API TestPanel : public Panel {
private:
	CSize	m_ClientSize;
public:
	TestPanel(Frame & f) 
		: Panel(f) 
	{
		SetCaption("Test");
		SetAlignment(ALIGN_TOP);
		m_ClientSize = CSize(50, 50);
	}
protected:
	virtual CSize GetMinClientSize() const
		{ return m_ClientSize; }
};

/**
 * Panel bar at the left side without splitter
 */
class ToolPanelBar : public PanelBar {
public:
	ToolPanelBar(Frame & f);
	virtual CRect Bounds() const;
	virtual void HandlePaint(CDC * pDC, const CRect &);
	virtual CSize ClientSize() const;
	virtual CSize GetMinWindowSize() const;
	virtual void LayoutControls();
};

/**
 * Panel bar at the right side
 */
class RightPanelBar : public PanelBar {
public:
	RightPanelBar(Frame & f);
	virtual CRect Bounds() const;
	virtual bool Visible() const;
};

/**
 * Panel bar at the bottom side
 */
class BottomPanelBar : public PanelBar {
public:
	BottomPanelBar(Frame & f);
	virtual CRect Bounds() const;
	virtual bool Visible() const;
};

} // My